<template>
  <div
    class="form-item"
    :class="{ focus: focus, error: error }"
    @focus="handleFocus"
    @blur="handleBlur"
  >
    <input
      class="input"
      :type="inputType"
      :placeholder="prop.placeholder"
      :value="inputValue"
      @input="$emit('input', $event.target.value)"
      @focus="handleFocus"
      @blur="handleBlur"
    />
    <div class="operation" v-if="prop.formItemType">
      <template v-if="prop.formItemType == 'password'">
        <i
          class="icon iconfont"
          :class="visiblePwd ? 'icon-bukejian' : 'icon-yuedukejian'"
          @click="visiblePwd = !visiblePwd"
        >
        </i>
      </template>
      <button
        class="send-verify-code"
        @click.stop.prevent="sendVerifyCode"
        v-if="prop.formItemType == 'verifyCode'"
      >
        获取验证码
      </button>
    </div>
  </div>
</template>

<script>
import Schema from 'async-validator'
export default {
  name: 'FormItem',
  inject: ['form'],
  model: {
    prop: 'inputValue',
    event: 'input'
  },
  props: {
    inputValue: {
      type: String,
      default: ''
    },
    prop: {
      require: true,
      type: Object,
      default: () => { },
    },
  },
  data() {
    return {
      error: false,
      focus: false,
      visiblePwd: false
    }
  },
  computed: {
    inputType() {
      if (this.prop.name != 'password') {
        return this.prop.type ? this.prop.type : 'text'
      }
      return this.visiblePwd ? 'text' : 'password'
    }
  },
  methods: {
    async validate() {
      // 校验方法
      // 1.拿到对应的表单值
      const value = this.prop.vModel
      const rule = this.form.rules[this.prop.name]

      const success = { status: true, name: this.prop.name }
      if (!rule) return success

      // 参数为校验规则键值对
      const schema = new Schema({ [this.prop.name]: rule })
      // 开始验证，第一个参数为数据源

      return new Promise((resolve, reject) => {
        schema.validate({ [this.prop.name]: value }, errors => {
          if (errors) {
            this.error = true
            resolve({ status: false, msg: errors[0].message, name: this.prop.name })
          } else {
            this.error = false
            resolve(success)
          }
        })
      })
    },
    handleFocus() {
      this.focus = true
    },
    handleBlur() {
      this.focus = false
    },
    async sendVerifyCode() {
      const form = this.form
      const res = await form.$children.find(children => children.prop && children.prop.name == form.type).validate()
      if (res.status) {
        form.$emit('sendCode', form.model[form.type].vModel)
        return
      }
      form.$emit('errMsg', res.msg)
    },
    init() {
      Object.values(this.form.model).forEach(item => item.vModel = '')
      this.focus = false
      this.error = false
    }
  },
  watch: {
    'form.type'() {
      this.init()
    }
  }
}
</script>

<style lang="less" scoped>
.form-item {
  display: flex;
  align-items: center;
  width: 100%;
  height: 44px;
  background-color: #24252f;
  border-radius: 5px;
  overflow: hidden;
  outline: none;
  transition: all 0.3s;
  border: 1px solid #333542;
  box-sizing: border-box;

  &:not(:last-of-type) {
    margin-bottom: 15px;
  }

  &.focus {
    box-shadow: rgba(233, 177, 14, 0.25) 0 0 0 3px;
    border-color: #ffc20b;
  }

  &.error {
    border-color: #ff5c5c;
    animation-name: error;
    animation-duration: 0.3s;
  }

  &.focus.error {
    box-shadow: rgba(255, 92, 92, 0.25) 0 0 0 3px;
  }

  .input {
    padding: 12px;
    box-sizing: border-box;
    height: 100%;
    display: inline-block;
    flex: 1 1;
    width: min-content;
    outline: none;
    border: none;
    background: none;
    font-size: 14px;
    line-height: 18px;
    color: #c3c3e2;

    &::placeholder {
      font-size: 13px;
      color: #c3c3e2a1;
    }
  }
  .operation {
    flex: 0 0;
    // width: min-content;

    .icon {
      margin-right: 10px;
      line-height: 24px;
      height: 24px;
      width: 24px;
      font-size: 24px;
      color: #c3c3e2;
    }

    .send-verify-code {
      display: inline-block;
      width: min-content;
      white-space: nowrap;
      outline: none;
      border: none;
      position: relative;
      padding: 0 8px;
      box-sizing: border-box;
      font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif;
      font-weight: 500;
      line-height: 1.75;
      height: 36px;
      line-height: 36px;
      color: #c3c3e2;
      background: none;
      font-size: 14px;
      border-radius: 5px;
      transition: background-color 0.3s;
      &:hover {
        background-color: rgba(195, 195, 226, 0.04);
      }
    }
  }
}

@keyframes error {
  0% {
    transform: translateX(-5px);
  }
  25% {
    transform: translateX(5px);
  }
  75% {
    transform: translateX(-5px);
  }
  100% {
    transform: translateX(5px);
  }
}
</style>